package com.plm.maque.service.impl;

import com.plm.maque.entity.ImageInfo;
import com.plm.maque.entity.MongoImage;
import com.plm.maque.entity.User;
import com.plm.maque.mongo.ImageOperate;
import com.plm.maque.service.ImageInfoService;
import com.plm.maque.service.ImageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author Limi
 * @create 2019-04-21 16:13
 */
@Slf4j
@Service
public class ImageServiceImpl implements ImageService {

    @Autowired
    private ImageOperate imageOperate;
    @Autowired
    private ImageInfoService imageInfoService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ImageInfo uploadImage(HttpServletRequest request, User user) {
        //文件自带属性
        MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
        MultipartFile file = req.getFile("imageFile");
        //String imgSize = req.getParameter("size");
        Long imgSize = file.getSize();

        if (imgSize/1024 - 1048576 > 0) {
            throw new RuntimeException("图片超过1M");
        }

        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = 0;
            int height = 0;
            if (null != bufferedImage) {
                width = bufferedImage.getWidth();
                height = bufferedImage.getHeight();
            }
            log.info("上传的图片，宽：{}, 高：{}", width, height);

            //保存到mongodb
            MongoImage mongoImage = saveMongoImage(file);

            String objectId = mongoImage.getDataId();

            //构建图片信息
            ImageInfo imageInfo = new ImageInfo();
            String imageName = file.getOriginalFilename();

            String id = UUID.randomUUID().toString().replaceAll("-","");
            imageInfo.setId(id)
                    .setMongoId(objectId)
                    .setImgName(imageName.substring(0, imageName.lastIndexOf(".")))
                    .setImgSuffix(imageName.substring(imageName.lastIndexOf(".")+1))
                    .setImgSize(String.valueOf(file.getSize()))
                    .setStatus("1")//0无效，1有效
                    .setCreatorId(String.valueOf(user.getUserId()))
                    .setCreatorName(user.getUsername())
                    .setWidth(String.valueOf(width))
                    .setHeight(String.valueOf(height))
                    .setCreateDate(new Date());

            boolean saveImageInfo = imageInfoService.saveImageInfo(imageInfo);
            if (saveImageInfo == false) {
                return null;
            }

            return imageInfo;

        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return null;
    }

    /**
     * 把文件的相关信息设置到对应的实体中
     * @param file
     * @return
     */
    private MongoImage saveMongoImage(MultipartFile file) {
        MongoImage mongoImage = new MongoImage();
        mongoImage.setFileName(file.getOriginalFilename())
                .setContentType(file.getContentType());
        try (InputStream in = file.getInputStream()) {
            mongoImage.setInputStream(in)
                      .setContentType(file.getContentType());
            String objectId = imageOperate.saveImageToMongoDB(mongoImage);
            mongoImage.setDataId(objectId);
        } catch (IOException e) {
            log.error("保存到mongodb出错");
        }

        return mongoImage;
    }

    @Override
    public void getImage(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        ImageInfo imageInfo = imageInfoService.getImageInfo(map);
        String imgName = imageInfo.getImgName() + "." + imageInfo.getImgSuffix();
        MongoImage mongoImage = imageOperate.getImageFromMongoDB(imageInfo.getMongoId());
        if (mongoImage == null) {
           throw new RuntimeException("查询图片失败");
        }

        try (InputStream is = mongoImage.getInputStream(); OutputStream os = response.getOutputStream()) {
            if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0) {
                imgName = URLEncoder.encode(imgName, "UTF-8");//IE浏览器
            } else {
                imgName = new String(imgName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
            }
            //response.setContentType("image/jpeg");
            //response.setHeader("Location", imgName);
            //response.setHeader("Content-Disposition", "attachment; filename=\"" + imgName + "\"");
            response.setHeader("Cache-Control", "no-store, no-cache");
            response.setContentType("image/jpeg");

            byte[] buffer = new byte[8192];//每次从文件里读取8K
            int count;
            while (true) {
                count = is.read(buffer);//将字节读取到缓冲区
                if (count <= 0) {
                    break;
                }
                os.write(buffer, 0, count);//向客户输出文件
            }

        } catch (Exception e) {
             log.error("获取图片出现异常：" + e.getMessage());
        }


    }

    @Override
    public ResponseEntity<byte[]> getImage(String id) {
        return null;
    }

    @Override
    public List<ImageInfo> query(ImageInfo imageInfo, User user) {
        return null;
    }

    @Override
    public void delete(ImageInfo imageInfo, User user) {

    }

    @Override
    public List<ImageInfo> queryByDirectoryId(String directoryId, User user) {
        return null;
    }

    @Override
    public void updateByPrimaryKeySelective(ImageInfo imageInfo, User user) {

    }

    @Override
    public String uploadThumbnail(HttpServletRequest request, User user) {
        return null;
    }
}
